(function($) {
	$.Cronz = function(el, options) {
		$.Cronz.ah.add(el, 0, options);
	};

	$.fn.cronz = function(options) {
		return this.each(function(idx){
			$.Cronz.ah.add(this, idx, options);
		});
	};

	$.fn.mousehold = function(x, f){
        var t,ctr,that;
        var i = 0;
        return this.each(function() {
            $(this).mousedown(function(){
                that = this;
                i = 2; 
                ctr = 0; 
                t = setInterval(function(){f.call(that, ctr++);}, x);
            });
            $(this).mouseup(function(){clearInterval(t);});
            $(this).mouseout(function(){
                if(i == 1) f.call(this, 1);
                i = i == 1 ? 0 : i;
                clearInterval(t);
            });
        })
	}
	
	$.Cronz.ah = {
	    options: {
			mode: 24,
			div_id: "test_div",
			onOK : false,
			onClose : false,
			fadeSpeed: 'slow',
			closeLink: '<a href="javascript:void(0);" class="czClose">Close</a><a href="javascript:void(0);" class="czOK">OK</a><br />'
	    },
		slidecall: 0,
		czHrChange: function(idx, dir, slide){
			var val = parseInt($('#czHr' + idx).val(), 10);
			var top_hr = this.options.mode == 24 ? 23 : 12;
			var bot_hr = this.options.mode == 24 ? 0 : 1;
			var newhr = dir == 'up' ? (val == top_hr ? bot_hr : val+1) : (val < (bot_hr+1) ? top_hr : val-1);
			newhr = this.options.mode == 24 ? this.leading_zeros(newhr,2) : newhr;
			$('#czHr' + idx).val(newhr);
			if(slide) this.callfn('this.slide',[idx, 2]);
			return newhr;
		},
		czMinChange: function(idx, dir){
			var val = parseInt($('#czMin' + idx).val(), 10);
			var newmin = dir == 'up' ? (val > 58 ? 0 : val+1) : (val < 1 ? 59 : val-1);
			$('#czMin' + idx).val(this.leading_zeros(newmin,2));
			if((newmin == 0 && dir == 'up')||(newmin == 59 && dir == 'down')) this.czHrChange(idx, dir, false);
			this.callfn('this.slide', [idx, 1]);
			return newmin;
		},
		czSecChange: function(idx, dir){
			var val = parseInt($('#czSec' + idx).val(), 10);
			var newsec = dir == 'up' ? (val > 58 ? 0 : val+1) : (val < 1 ? 59 : val-1);
			if((newsec == 0 && dir == 'up')||(newsec == 59 && dir == 'down')) this.czMinChange(idx, dir);
			newsec = this.leading_zeros(newsec,2);
			$('#czSec' + idx).val(newsec);
			return newsec;
		},
		getTime: function(idx){
			var hr = $('#czHr' + idx).val();
			var min = $('#czMin' + idx).val();
			var sec = $('#czSec' + idx).val();
			var time = hr + ':' + min + ':' + sec;
			return {'time':time, 'hr':hr, 'min':min, 'sec':sec};
		},
		leading_zeros: function(n, total_digits){
			var str = '' + n;
			while (str.length < total_digits) str = '0' + n;
			return str;
		},
		formatHour: function(hr){
			return (this.options.mode == 24) ? this.leading_zeros(parseInt(hr,10),2) : (hr == 0) ? 12 : parseInt(hr,10); 
		},
		callfn: function(fn, params){eval(fn + '('+ params.join(',') + ');');},
		slide: function(idx, inc){
			var x = parseInt($('#czSlide' + idx).slider('value'),10);
			var newpos = (60 * parseInt($('#czHr' + idx).val(),10)) + (parseInt($('#czMin' + idx).val(),10));
			newpos = newpos == 0 ? 1 : newpos;
			if(this.options.mode == 12 && $('#czHr' + idx).val() == 12 && $('#czMin' + idx).val() > 0) newpos = $('#czMin' + idx).val();
			$('#czSlide' + idx).slider('moveTo',newpos);
		},
		formatTime: function(idx){
			$('#czHr' + idx).val(this.formatHour($('#czHr' + idx).val()));
			$('#czMin' + idx).val(this.leading_zeros(parseInt($('#czMin' + idx).val(),10),2));
			$('#czSec' + idx).val(this.leading_zeros(parseInt($('#czSec' + idx).val(),10),2));
		},
		add: function(el, idx, options){
		
			if(options) $.extend(this.options, options);
			var cz = this;
			$(el)
				.addClass('czInput')
				.attr('id','czInput' + idx);
			$('body').append('<div class="czContainer" id="cz' + idx +'"></div>');
			$('#cz' + idx).append(cz.options.closeLink); // add close link to container
			$([{name:'czHr', display:true, fieldNamePrfx:'hr'}, {name:'czMin', display:true, fieldNamePrfx:'min'}, {name:'czSec', display:true, fieldNamePrfx:'sec'}]).each(function(){
				if($(this)[0].name){
					var thisfn = 'this.' + $(this)[0].name + 'Change'; // get function name
					var thisel = "$('#" + $(this)[0].name + idx + "')"; // get element
					$('#cz' + idx)
						.append('<input type="text" name="' + $(this)[0].fieldNamePrfx + '" id="' + $(this)[0].name + idx + '" class="' + $(this)[0].name + '" value="00" />')
						.append('<div class="updownimg"><a href="javascript:void(0);" class="czup" id="' + $(this)[0].name + 'Up' + idx + '" title="Up">Up</a><a href="javascript:void(0);" class="czdown" id="' + $(this)[0].name + 'Down' + idx + '" title="Down">Down</a></div>');
					$('#' + $(this)[0].name + 'Up' + idx).unbind().mousehold(100, function(i){
						if(i>3) cz.callfn(thisfn, [idx, "'up'", 'true']);
						cz.slidecall=0;
					});
					$('#' + $(this)[0].name + 'Down' + idx).unbind().mousehold(100, function(i){
						if(i>3) cz.callfn(thisfn, [idx, "'down'", 'true']);
						cz.slidecall=0;
					});
					$('#' + $(this)[0].name + 'Up' + idx).click(function(){
						cz.callfn(thisfn, [idx, "'up'", 'true']);
						cz.slidecall=0;
					});
					$('#' + $(this)[0].name + 'Down' + idx).click(function(){
						cz.callfn(thisfn, [idx, "'down'", 'true']);
						cz.slidecall=0;
					});
					$('#czHr' + idx + ',#czMin' + idx).keyup(function(){
						cz.callfn('this.slide', [idx,0]);
						cz.formatTime(idx);
						cz.slidecall=0;
					});
				}
			});
			$('#cz' + idx)
				.append('<div style="clear:both;"></div>')
				.append('<div style="width:180px;"><div id="czSlide' + idx + '" class="ui-slider-1"><div class="ui-slider-handle"></div></div></div>');
			$('#czSlide' + idx).hide();
			$(el).click(function(){ // show time box
				$('#cz' + idx).css('left', $(el).position().left + 'px').css('top', $(el).position().top + $(el).height() + 'px');
				$('#cz' + idx).fadeIn(cz.options.fadeSpeed, function(){
					var slidemax = cz.options.mode == 24 ? 1435 : 715;
					$('#czSlide' + idx).slider({'min':1, 'max':slidemax, 'stepping':5, 'slide': function(e,ui) {
							if(cz.slidecall == 1){								
								$('#czHr' + idx).val(cz.formatHour(parseInt((ui.value/60),10)));
								var newmin = cz.options.mode == 12 && parseInt($('#czMin' + idx).val(),10) == 0 && $('#czHr' + idx).val() == '12' ? '01' : parseInt((ui.value%60),10);
								$('#czMin' + idx).val(cz.leading_zeros(newmin, 2));
							}
						}
					});
					
					$('#czSlide' + idx).show();
					var rx = /([\d]{1,2}):([\d]{1,2}):([\d]{1,2})/;
					var match = rx.exec($(el).val());
					if (match != null) {
						$('#czHr' + idx).val(match[1]);
						$('#czMin' + idx).val(match[2]);
						$('#czSec' + idx).val(match[3]);
						cz.slide(idx,0);
					} else {
						$('#czHr' + idx).val(0);
						$('#czMin' + idx).val(0);
						$('#czSec' + idx).val(0);
					}
					cz.formatTime(idx);
				});
				thisel = this;
				$('.czClose').unbind('click');
				$('.czClose').click(function(){ // close link clicked
					$(this).parent().fadeOut(cz.options.fadeSpeed);
					if(cz.options.onClose) cz.options.onClose(cz.getTime(idx)); // do 'onClose' callback
				});
				$('.czOK').unbind('click');
				$('.czOK').click(function(){ // ok link clicked
					$(thisel).val(cz.getTime(idx).time);
					$(this).parent().fadeOut(cz.options.fadeSpeed);
					if(cz.options.onOK) cz.options.onOK(cz.getTime(idx)); // do 'onOk' callback
				});
			});
			$('.ui-slider-handle').mousedown(function(){cz.slidecall=1;});
		}
	}
})($);